package es.usj.redes.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import es.usj.redes.dto.Enviado;
import es.usj.redes.dto.MailEnviado;
import es.usj.redes.dto.Users;
/**
 * Clase que implementa el acceso a la tabla Enviado para JDBC.
 * <p>En esta clase se encapsulan los metodos necesarios para trabajar con la 
 * tabla Enviado, la cual esta descrita en el Bean {@link es.usj.redes.dto.Enviado enviado}
 * <br/>
 * Implementa la interfaz {@link es.usj.redes.dao.EnviadoDAO EnviadoDAO} para dotar a la clase de robustez 
 * empleando el patron DAOFactory.
 * En esta clase se especifica el acceso a la BBDD para la tabla enviados mediante 
 * JDBC, creando en cada metodo un objeto {@link java.sql.Connection} con los 
 * datos especificados en {@link es.usj.redes.dao.DataSource} para acceder.
 * 
 * Son metodos CRUD (Create, Read, Update, Delete) tipicos de acceso a Bases de datos.
 * Donde en cada uno tiene la misma estructura, crear el objeto Connection, el resultSet
 * el prepareStatement y a partir de la SQL de cada metodo obtener o introducir (en caso 
 * de update) el valor correspondiente y finalmente devolver si se lista, 
 * en caso contrario no devuelve nada la BBDD, el objeto correspondiente.
 * @version 1.2
 * @since 1.0
 *
 */
public class EnviadoJdbcDAO implements EnviadoDAO {
    public void create(Enviado obj) throws DAOException {
        Connection c = null;
        ResultSet result = null;
        PreparedStatement statement = null;
        try {
            int i=1;
            c = DataSource.getConnection();
            statement = c.prepareStatement("insert into enviados (idmail, idmailusers, idusuario, leido, fechaentregado, eliminado) values (?, ?, ?, ?, ?, ?)");
            statement.setInt(i++, obj.getIdMail());
            statement.setInt(i++, obj.getIdMailUsers());
            statement.setInt(i++, obj.getIdUsuario());
            statement.setBoolean(i++, obj.getLeido());
            statement.setDate(i++, new java.sql.Date(obj.getFechaEntregado().getTime()));
            statement.setBoolean(i++, obj.getEliminado());
            int n = statement.executeUpdate();
            if(n == 0)
                    throw new DAOException("No rows updated");
            result = statement.getGeneratedKeys();
            if(!result.next())
                    throw new DAOException("No generated keys");
            i=1;
            obj.setIdMailUsers(result.getInt(i++));
        } catch(SQLException sqle) {
            throw new DAOException(sqle);
        } finally {
            if(result != null)
                    try { result.close(); } catch(SQLException ignored) { }
            if(statement != null)
                    try { statement.close(); } catch(SQLException ignored) { }
            if(c != null)
                    try { c.close(); } catch(SQLException ignored) { }
        }
    }

    public void delete(int idMailUsers) throws DAOException {
        Connection c = null;
        PreparedStatement statement = null;
        try {
            int i=1;
            c = DataSource.getConnection();
            statement = c.prepareStatement("delete from enviados where idmailusers=?");
            statement.setInt(i++, idMailUsers);
            int n = statement.executeUpdate();
            if(n == 0)
                    throw new DAOException("No rows updated");
        } catch(SQLException sqle) {
            throw new DAOException(sqle);
        } finally {
            if(statement != null)
                    try { statement.close(); } catch(SQLException ignored) { }
            if(c != null)
                    try { c.close(); } catch(SQLException ignored) { }
        }
    }

    public void update(Enviado obj) throws DAOException {
        Connection c = null;
        PreparedStatement statement = null;
        try {
            int i=1;
            c = DataSource.getConnection();
            StringBuffer sb = new StringBuffer("update enviados set idmail=?, idusuario=?, leido=?, fechaentregado=?, eliminado=?");
            sb.append(" where idmailusers=?");
            statement = c.prepareStatement(sb.toString());
            statement.setInt(i++, obj.getIdMail());
            statement.setInt(i++, obj.getIdUsuario());
            statement.setBoolean(i++, obj.getLeido());
            //statement.setDate(i++, (Date) new java.util.Date(obj.getFechaEntregado().getTime()));
            statement.setTimestamp(i++, new java.sql.Timestamp(new java.util.Date().getTime()));
            statement.setBoolean(i++, obj.getEliminado());
            statement.setInt(i++, obj.getIdMailUsers());
            int n = statement.executeUpdate();
            if(n == 0)
                    throw new DAOException("No rows updated");
        } catch(SQLException sqle) {
            throw new DAOException(sqle);
        } finally {
            if(statement != null)
                    try { statement.close(); } catch(SQLException ignored) { }
            if(c != null)
                    try { c.close(); } catch(SQLException ignored) { }
        }
    }

    public Enviado read(int idMailUsers) throws DAOException {
        Connection c = null;
        PreparedStatement statement = null;
        ResultSet result = null;
        try {
            int i=1;
            c = DataSource.getConnection();
            statement = c.prepareStatement("select idmailusers, idmail, idusuario, leido, fechaentregado, eliminado from enviados where idmail=?", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            statement.setInt(i++, idMailUsers);
            result = statement.executeQuery();
            Enviado obj = null;
            if(result.next()) {
            	i=1;
                    obj = new Enviado();
                    obj.setIdMailUsers(result.getInt(i++));
                    obj.setIdMail(result.getInt(i++));
                    obj.setIdUsuario(result.getInt(i++));
                    obj.setLeido(result.getBoolean(i++));
                    obj.setFechaEntregado(result.getDate(i++));
                    obj.setEliminado(result.getBoolean(i++));
                    return obj;
            } else {
                    throw new DAOException("No such instance exception");
            }
        } catch(SQLException sqle) {
            throw new DAOException(sqle);
        } finally {
            if(result != null)
                    try { result.close(); } catch(SQLException ignored) { }
            if(statement != null)
                    try { statement.close(); } catch(SQLException ignored) { }
            if(c != null)
                    try { c.close(); } catch(SQLException ignored) { }
        }
    }


	public List<Enviado> listAll() throws DAOException {
		Connection c = null;
		PreparedStatement statement = null;
		ResultSet result = null;
		List list = new ArrayList<Users>();
		try {
			int i=1;
			c = DataSource.getConnection();
			statement = c.prepareStatement("select idmail, idmailusers, idusuario, leido, fechaentregado, eliminado from enviados");
		
			result = statement.executeQuery();
			Enviado obj = null;
			while(result.next()) {
				i = 1;
				obj = new Enviado();
				obj.setIdMail(result.getInt(i++));
				obj.setIdMailUsers(result.getInt(i++));
				obj.setIdUsuario(result.getInt(i++));
				obj.setLeido(result.getBoolean(i++));
				obj.setFechaEntregado(result.getDate(i++));
				obj.setEliminado(result.getBoolean(i++));
				list.add(obj);
			}
			return list;
		} catch(SQLException sqle) {
			throw new DAOException(sqle);
		} finally {
			if(result != null)
				try { result.close(); } catch(SQLException ignored) { }
			if(statement != null)
				try { statement.close(); } catch(SQLException ignored) { }
			if(c != null)
				try { c.close(); } catch(SQLException ignored) { }
		}
	}


	public List<Enviado> listByUsuario(int idUsuario) throws DAOException {
		Connection c = null;
		PreparedStatement statement = null;
		ResultSet result = null;
		List list = new ArrayList<Users>();
		try {
			int i=1;
			c = DataSource.getConnection();
			statement = c.prepareStatement("select idmail, idmailusers, idusuario, leido, fechaentregado, eliminado from enviados where idusuario=?");
		statement.setInt(i, idUsuario);
			result = statement.executeQuery();
			Enviado obj = null;
			while(result.next()) {
				i = 1;
				obj = new Enviado();
				obj.setIdMail(result.getInt(i++));
				obj.setIdMailUsers(result.getInt(i++));
				obj.setIdUsuario(result.getInt(i++));
				obj.setLeido(result.getBoolean(i++));
				obj.setFechaEntregado(result.getDate(i++));
				obj.setEliminado(result.getBoolean(i++));
				list.add(obj);
			}
			return list;
		} catch(SQLException sqle) {
			throw new DAOException(sqle);
		} finally {
			if(result != null)
				try { result.close(); } catch(SQLException ignored) { }
			if(statement != null)
				try { statement.close(); } catch(SQLException ignored) { }
			if(c != null)
				try { c.close(); } catch(SQLException ignored) { }
		}
	}
	/**
	 * Identifica los Mails enviados que no han sido eliminados de un usuario.
	 * 
	 * A partir del ID del usuario que se especifica en la firma del metodo
	 * se filtraran aquellos mails que cumplan la condicion de no ser elimiandos.
	 * 
	 * @param idUsuario
	 * @return
	 * @throws DAOException
	 */
	public List<MailEnviado> listEnviadosNoEliminadosFromUser(int idUsuario) throws DAOException {
		Connection c = null;
		PreparedStatement statement = null;
		ResultSet result = null;
		List list = new ArrayList<Users>();
		try {
			int i=1;
			c = DataSource.getConnection();
			statement = c.prepareStatement("Select m.idmail as idmail, m.idusuario as fromuser, m.subject, m.texto, m.fechaenviado, e.idmailusers as idenviado, e.idusuario as touser, e.leido, e.fechaentregado, e.eliminado from mail as m, enviados as e where m.idmail = e.idmail and e.eliminado=false and m.idusuario=?");
			statement.setInt(1, idUsuario);
			result = statement.executeQuery();
			MailEnviado obj = null;
			while(result.next()) {
				i = 1;
				obj = new MailEnviado();
				obj.setIdMail(result.getInt(i++));
				obj.setIdUsuarioFrom(result.getInt(i++));
				obj.setSubject(result.getString(i++));
				obj.setTexto(result.getString(i++));
				obj.setFechaEnviado(result.getDate(i++));
				obj.setIdMailEnviado(result.getInt(i++));
				obj.setIdUsuarioTo(result.getInt(i++));
				obj.setLeido(result.getBoolean(i++));
				obj.setFechaEntregado(result.getDate(i++));
				obj.setEliminado(result.getBoolean(i++));
				list.add(obj);
			}
			return list;
		} catch(SQLException sqle) {
			throw new DAOException(sqle);
		} finally {
			if(result != null)
				try { result.close(); } catch(SQLException ignored) { }
			if(statement != null)
				try { statement.close(); } catch(SQLException ignored) { }
			if(c != null)
				try { c.close(); } catch(SQLException ignored) { }
		}
	}
	

}
